package cn.edu.sjtu.todo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import cn.edu.sjtu.todo.nodes.MethodNode;

public class Cfg {
	
	protected Map<String, MethodNode> methodNameMap;
	
	public Cfg() {
		methodNameMap = new HashMap<String, MethodNode>();
	}
	
	public Map<String, MethodNode> getMethodNameMap() {
		return methodNameMap;
	}
	
	public void addNewMethod(MethodNode mn) {
		methodNameMap.put(mn.getMethodName(), mn);
	}
	
	public MethodNode getMethodNode(String methodName) {
		if (methodNameMap.containsKey(methodName)) {
			return methodNameMap.get(methodName);
		}
		return MethodNode.createMethodNode(methodName, methodName.substring(0, methodName.lastIndexOf(".")), "", -1, -1);
	}
	
	public void addCfgEdge(String sname, String ename) {
		MethodNode s = getMethodNode(sname);
		MethodNode e = getMethodNode(ename);
		
		s.addOutMethod(ename);
		e.addInMethod(sname);
	}
	
	public MethodNode[] getMethods() {
		ArrayList<MethodNode> list = new ArrayList<MethodNode>();
		Iterator i = methodNameMap.entrySet().iterator();
		while (i.hasNext()) {
			Map.Entry e = (Entry)i.next();		
			MethodNode mn = (MethodNode)e.getValue();
			list.add(mn);
		}
		return list.toArray(new MethodNode[list.size()]);
	}
	
	public MethodNode[] getSourceMethods() {
		ArrayList<MethodNode> list = new ArrayList<MethodNode>();
		Iterator i = methodNameMap.entrySet().iterator();
		while (i.hasNext()) {
			Map.Entry e = (Entry)i.next();		
			MethodNode mn = (MethodNode)e.getValue();
			if (mn.getInMethods().size() == 0) {
				list.add(mn);
			}
		}
		return list.toArray(new MethodNode[list.size()]);
	}
	
	// for test
	public void printMethodMap() {
		Iterator i = methodNameMap.entrySet().iterator();
		while (i.hasNext()) {
			Map.Entry e = (Entry)i.next();
			System.out.println("Method: " + e.getKey().toString());
			
			MethodNode mn = (MethodNode)e.getValue();
			
			System.out.println("\tInMethod: ");
			for (String m : mn.getInMethods()) {
				System.out.println("\t\t" + m);
			}
			System.out.println("\tOutMethod: ");
			for (String m : mn.getOutMethods()) {
				System.out.println("\t\t" + m);
			}
		}
	}
}